package com.ruoyi.system.service.impl;

import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.ruoyi.common.exception.user.TemplateException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.file.FastDFSUtil;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.system.domain.SysCertificate;
import com.ruoyi.system.domain.SysOrganization;
import com.ruoyi.system.domain.SyseEventsPosted;
import com.ruoyi.system.domain.mongodb.Teacher;
import com.ruoyi.system.domain.mongodb.Users;
import com.ruoyi.system.mapper.SysCertificateMapper;
import com.ruoyi.system.mapper.SysEventsPostedMapper;
import com.ruoyi.system.mapper.SysOrganizationMapper;
import com.ruoyi.system.mongo.StudentDao;
import com.ruoyi.system.mongo.SysUserDao;
import com.ruoyi.system.mongo.TeacherDao;
import com.ruoyi.system.service.ISysEventsPostedService;
import com.ruoyi.system.service.ISysCertificateService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.ISysUsersService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author 柳
 * @Date 2021/2/24
 * @Description TODO
 */
@Service
public class SysCertificateServiceImpl implements ISysCertificateService {

    @Autowired
    private SysCertificateMapper sysCertificateMapper;

    @Autowired
    private SysOrganizationMapper sysOrganizationMapper;

    @Autowired
    private StudentDao studentDao;

    @Autowired
    private SysEventsPostedMapper sysEventsPostedMapper;

    @Autowired
    private ISysEventsPostedService iSysEventsPostedService;

    @Autowired
    private SysUserDao SysUserDao;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 文件服务器工具类
     */
    @Autowired
    private FastDFSUtil fastDFSUtil;

    /**
     *
     * @param sysCertificate
     * @return
     */
    @Override
    public Integer queryCertificateIsNull(SysCertificate sysCertificate) {
        return sysCertificateMapper.queryCertificateIsNull(sysCertificate);
    }

    /**
     * 教师页面查询所有证书信息
     * @param sysCertificate
     * @return
     */
    @Override
    public List<SysCertificate> querySysCertificatesByTeacher(SysCertificate sysCertificate) {
        //获取学生信息集合
        List<Users> usersList = studentDao.selectUsersAlll();
        //获取证书信息集合
        List<SysCertificate> SysCertificateList=  sysCertificateMapper.querySysCertificatesByTeacher(sysCertificate);
        //循环
        for (Users users : usersList) {
            for (SysCertificate querySysCertificate : SysCertificateList) {
                //判断学生表id字段和证书信息表的stuid字段是否对应
                if(querySysCertificate.getStuid().equals(users.getId())){
                    //对应则将证书信息表的学生姓名改为用户表中的nickname
                    querySysCertificate.setName(users.getNickname());
                    sysCertificateMapper.updateStunameById(querySysCertificate);
                }
            }
        }

        return SysCertificateList;
    }

    /**
     * 根据学生id查询该学生的证书信息
     * @param stuid
     * @return
     */
    @Override
    public List<SysCertificate> querySysCertificateByStuid(String stuid) {
        List<SysCertificate> sysCertificateList = sysCertificateMapper.querySysCertificateByStuid(stuid);
        return sysCertificateList;
    }

    /**
     * 查询所有证书信息
     * @param sysCertificate
     * @return
     */
    @Override
    public List<SysCertificate> querySysCertificates(SysCertificate sysCertificate) {
        //获取学生信息集合
        List<Users> usersList = studentDao.selectUsersAlll();
        //获取证书信息集合
        List<SysCertificate> SysCertificateList=  sysCertificateMapper.querySysCertificates(sysCertificate);
        //循环
        for (Users users : usersList) {
            for (SysCertificate querySysCertificate : SysCertificateList) {
                //判断学生表id字段和证书信息表的stuid字段是否对应
                if(querySysCertificate.getStuid().equals(users.getId())){
                        //对应则将证书信息表的学生姓名改为用户表中的nickname
                        querySysCertificate.setName(users.getNickname());
                        sysCertificateMapper.updateStunameById(querySysCertificate);
                }
            }
        }

        return SysCertificateList;
    }

    /**
     * 颁发证书(添加证书信息)
     * @param sysCertificate
     */
    @Override
    public void saveSysCertificates(SysCertificate sysCertificate) throws TemplateException {
        //数据准备
        Integer cid=0;
        //获取当前时间转换字符串用于证书编号
        Date date=new Date();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
        String format = sdf.format(date);
        String pdfPath="";

        //根据教师id查询教师名称
        String tname = SysUserDao.queryUserById(sysCertificate.getTeacher()).getRealname();
        if(StringUtils.isBlank(tname)){
            tname=SysUserDao.queryUserById(sysCertificate.getTeacher()).getNickname();
        }
        sysCertificate.setTname(tname);


//        //通过传递过来教师tid获得教师姓名并放入证书对象中
//        String tname = sysUserService.queryTnameByTid(sysCertificate.getTeacher());
//        sysCertificate.setTeacher(tname);
        //如果学生姓名为空
        if(StringUtils.isBlank(sysCertificate.getName())) {
            //获取学生信息集合
            List<Users> usersList = studentDao.selectUsersAlll();
            if (usersList.size() != 0) {
                for (Users users : usersList) {
                    if (users.getId().equals(sysCertificate.getStuid())) {
                        sysCertificate.setName(users.getRealname());
                        break;
                    }
                }
            }
        }
        //根据大赛id获取大赛信息
        SyseEventsPosted syseEventsPosted = iSysEventsPostedService.selectById(sysCertificate.getEpid());

        Integer count = sysCertificateMapper.queryCertificateidLately();
        if(count!=null){
            cid=count;
        }

        SysOrganization sysOrganization = sysOrganizationMapper.querySysOrganizationById(sysCertificate.getOrganizationid());

        //这里是选择某个模板
        String templateName = "template";
        String templateImage = "获奖证书模板.png";
        String rqcode = "rqcode.png";

        if (sysOrganization == null ||
                sysOrganization.getOrganizationname() == null ||
                sysOrganization.getFile() == null ||
                sysOrganization.getFilemsg() == null ||
                sysOrganization.getSeal() == null
            ) {
            throw new TemplateException(400, "当前学校没有在平台登记证书模板, 请联系平台管理员！");
        }


        String baseUrl = System.getProperty("user.dir");
        baseUrl = baseUrl.replaceAll("\\\\", "/");

        //组织数据填充到模板中
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //这里是给具体的某些字段赋值
        paramMap.put("name", sysCertificate.getName());
        paramMap.put("production", sysCertificate.getTitle());
        paramMap.put("activity", syseEventsPosted.getEptitle());
        paramMap.put("awards", sysCertificate.getAwards());
        paramMap.put("teacher", tname);
        paramMap.put("eventgroup", sysCertificate.getEventgroup());
        paramMap.put("organizations",sysOrganization.getOrganizationname());
        paramMap.put("issuetime", DateUtils.toChinese(sysCertificate.getIssuetime()));
        paramMap.put("certificateid", format+(cid+1));
        paramMap.put("organization", sysOrganization.getOrganizationname());
//        paramMap.put("file", sysOrganization.getFile());
//        paramMap.put("filemsg", sysOrganization.getFilemsg());
        paramMap.put("organizationurl", sysOrganization.getSeal());
        paramMap.put("backgroundurl", "file:///"+baseUrl+"//ruoyi-admin//src//main//resources//zhengshu//image//"+templateImage);
        paramMap.put("rqcode", "file:///"+baseUrl+"//ruoyi-admin//src//main//resources//zhengshu//image//"+rqcode);

        //生成pdf文件
        try {
            contractHandler(templateName, paramMap);

            pdfPath = fastDFSUtil.uploadFile(new File(System.getProperty("user.dir") + "\\ruoyi-admin\\src\\main\\resources\\zhengshu\\pdf\\pdfDemo.pdf"));
            sysCertificate.setPdfpath(pdfPath);

            String PdfFilePath = fastDFSUtil.getResAccessUrl(sysCertificate.getPdfpath());//文件服务器上pdf文件存放的地址
            int dpi=444;


            File file = null;

            URL urlfile;
            InputStream inputStream = null;
            OutputStream outputStream= null;
            PDDocument pdDocument;
            try {
                file = File.createTempFile("wx_image", ".png");
                //下载
                urlfile = new URL(PdfFilePath);
                inputStream = urlfile.openStream();
                outputStream= new FileOutputStream(file);

                int bytesRead = 0;
                byte[] buffer = new byte[8192];
                while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                    pdDocument = PDDocument.load(file);
                    PDFRenderer renderer = new PDFRenderer(pdDocument);
                    PdfReader reader = new PdfReader(PdfFilePath);
                    int pages = reader.getNumberOfPages();// 获取PDF页数
                    //System.out.println("PDF page number is:" + pages);
                    StringBuffer imgFilePath = null;
                    for (int i = 0; i < pages; i++) {
                        File dstFile = new File(PDFIMAGE+".png");
                        BufferedImage image = renderer.renderImageWithDPI(i, dpi);
                        ImageIO.write(image, "png", dstFile);// PNG
                        String s = fastDFSUtil.uploadFile(dstFile);
                        //System.out.println(fastDFSUtil.getResAccessUrl(s));
                        sysCertificate.setImage_url(fastDFSUtil.getResAccessUrl(s));
                    }
                    System.out.println("PDF文档转PNG图片成功！");
                    //颁发证书(添加证书信息)
                    sysCertificateMapper.saveSysCertificates(sysCertificate);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != outputStream) {
                        outputStream.close();
                    }
                    if (null != inputStream) {
                        inputStream.close();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


//    public static void main(String[] args) {
//        deleteFile(PDFIMAGE+".png");
//    }

    /**
     * 查找最近添加的证书信息的id
     * @return
     */
    @Override
    public Integer queryCertificateidLately() {
        return sysCertificateMapper.queryCertificateidLately();
    }

    /**
     * 删除证书信息
     * @param certificateid
     */
    @Override
    public void deleteSysCertificates(Integer certificateid) {
        //根据id查询证书信息
        SysCertificate sysCertificate = sysCertificateMapper.querySysCertificatesById(certificateid);
        //根据路径删除文件服务器上的证书文件
        fastDFSUtil.deleteFile(fastDFSUtil.getResAccessUrl(sysCertificate.getPdfpath()));
        //根据路径删除文件服务器上的证书图片文件
        fastDFSUtil.deleteFile(sysCertificate.getImage_url());
        sysCertificateMapper.deleteSysCertificates(certificateid);
    }

    /**
     * 根据id修改学生姓名
     * @param sysCertificate
     */
    @Override
    public void updateStunameById(SysCertificate sysCertificate) {
        sysCertificateMapper.updateStunameById(sysCertificate);
    }

    /**
     * 根据id查询证书信息
     * @param certificateid
     * @return
     */
    @Override
    public SysCertificate querySysCertificatesById(Integer certificateid) {
        return sysCertificateMapper.querySysCertificatesById(certificateid);
    }

    /**
     * 修改证书信息
     * @param sysCertificate
     */
    @Override
    public void updateSysCertificatesById(SysCertificate sysCertificate) {
        //数据准备
        //获取当前时间转换字符串用于证书编号
        Date date=new Date();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
        String format = sdf.format(date);
        
//        //根据教师id查询教师名称
//        String tname = sysUserService.queryTnameByTid(sysCertificate.getTeacher());
//        sysCertificate.setTname(tname);
        //获取学生信息集合
        List<Users> usersList = studentDao.selectUsersAlll();
        if(usersList.size()!=0){
            for (Users users : usersList) {
                if(users.getId().equals(sysCertificate.getStuid())){
                    sysCertificate.setName(users.getNickname());
                    break;
                }
            }
        }
        //根据大赛id获取大赛信息
        SyseEventsPosted syseEventsPosted = iSysEventsPostedService.selectById(sysCertificate.getEpid());

        //根据机构编号查询机构信息
        SysOrganization sysOrganization = sysOrganizationMapper.querySysOrganizationById(sysCertificate.getOrganizationid());


        //这里是选择某个模板
        String templateName = "template";
        String templateImage = "获奖证书模板.png";

//        if(!sysCertificate.getTemplate().equals("")&&sysCertificate.getTemplate()!=null&&sysCertificate.getTemplate().equals("template1")){
//            templateName = "template";
//            templateImage = "获奖证书模板.png";
//        }else if(!sysCertificate.getTemplate().equals("")&&sysCertificate.getTemplate()!=null&&sysCertificate.getTemplate().equals("template2")){
//            templateName = "template2";
//            templateImage = "获奖证书模板2.png";
//        }else if(!sysCertificate.getTemplate().equals("")&&sysCertificate.getTemplate()!=null&&sysCertificate.getTemplate().equals("template3")){
//            templateName = "template3";
//            templateImage = "获奖证书模板3.png";
//        }else{//没有选择默认第一种模板
//            templateName = "template";
//            templateImage = "获奖证书模板.png";
//        }

        String baseUrl = System.getProperty("user.dir");
        baseUrl = baseUrl.replaceAll("\\\\", "/");

        //组织数据填充到模板中
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //这里是给具体的某些字段赋值
        paramMap.put("name", sysCertificate.getName());
        paramMap.put("production", sysCertificate.getTitle());
        paramMap.put("activity", syseEventsPosted.getEptitle());
        paramMap.put("awards", sysCertificate.getAwards());
        paramMap.put("teacher", sysCertificate.getTeacher());
        paramMap.put("organizations",sysOrganization.getOrganizationname());
        paramMap.put("issuetime", DateUtils.toChinese(sysCertificate.getIssuetime()));
        paramMap.put("certificateid", format+sysCertificateMapper.queryCertificateidLately());
        paramMap.put("organization", sysOrganization.getOrganizationname());
//        paramMap.put("file", sysOrganization.getFile());
//        paramMap.put("filemsg", sysOrganization.getFilemsg());
        paramMap.put("organizationurl",  sysOrganization.getSeal());
        paramMap.put("backgroundurl", "file:///"+baseUrl+"//ruoyi-admin//src//main//resources//zhengshu//image//"+templateImage);

        /**
         * 生成的pdf文件的路径
         */
        String pdfPath = "";
        //生成pdf文件
        try {
            contractHandler(templateName, paramMap);

            pdfPath = fastDFSUtil.uploadFile(new File(System.getProperty("user.dir") + "\\ruoyi-admin\\src\\main\\resources\\zhengshu\\pdf\\pdfDemo.pdf"));
            sysCertificate.setPdfpath(pdfPath);

            String PdfFilePath = fastDFSUtil.getResAccessUrl(sysCertificate.getPdfpath());//文件服务器上pdf文件存放的地址
            int dpi=444;


            File file = null;

            URL urlfile;
            InputStream inputStream = null;
            OutputStream outputStream= null;
            PDDocument pdDocument;
            try {
                file = File.createTempFile("wx_image", ".png");
                //下载
                urlfile = new URL(PdfFilePath);
                inputStream = urlfile.openStream();
                outputStream= new FileOutputStream(file);

                int bytesRead = 0;
                byte[] buffer = new byte[8192];
                while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                pdDocument = PDDocument.load(file);
                PDFRenderer renderer = new PDFRenderer(pdDocument);
                PdfReader reader = new PdfReader(PdfFilePath);
                int pages = reader.getNumberOfPages();// 获取PDF页数
                //System.out.println("PDF page number is:" + pages);
                StringBuffer imgFilePath = null;
                for (int i = 0; i < pages; i++) {
                    File dstFile = new File(PDFIMAGE+".png");
                    BufferedImage image = renderer.renderImageWithDPI(i, dpi);
                    ImageIO.write(image, "png", dstFile);// PNG
                    String s = fastDFSUtil.uploadFile(dstFile);
                    //System.out.println(fastDFSUtil.getResAccessUrl(s));
                    sysCertificate.setImage_url(fastDFSUtil.getResAccessUrl(s));
                }
                System.out.println("PDF文档转PNG图片成功！");
                //修改证书信息(添加证书信息)
                sysCertificateMapper.updateSysCertificatesById(sysCertificate);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != outputStream) {
                        outputStream.close();
                    }
                    if (null != inputStream) {
                        inputStream.close();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    private static final String TEMPLATE = System.getProperty("user.dir")+"\\ruoyi-admin\\src\\main\\resources\\zhengshu\\ftl";//模板存储路径
    private static final String CONTRACT = System.getProperty("user.dir")+"\\ruoyi-admin\\src\\main\\resources\\zhengshu\\pdf";
    private static final String PDFIMAGE = System.getProperty("user.dir")+"\\ruoyi-admin\\src\\main\\resources\\zhengshu\\pdfimage";//模板存储路径

    private static final String IMAGENAME = "pdfDemo";//pdf文件名
    private static final String PDFNAME = "pdfDemo";//pdf文件名
    private static final String HTMLNAME = "pdfDemo";//html文件名



    public void contractHandler(String templateName,
                                Map<String, Object> paramMap) throws Exception {
        // 获取本地模板存储路径、合同文件存储路径
        String templatePath = TEMPLATE;
        String contractPath = CONTRACT;
        // 组装html和pdf合同的全路径URL
        String localHtmlUrl = contractPath + HTMLNAME + ".html";
        String localPdfPath = contractPath + "/";
        // 判断本地路径是否存在如果不存在则创建
        File localFile = new File(localPdfPath);
        if (!localFile.exists()) {
            localFile.mkdirs();
        }
        String localPdfUrl = localFile + "/" + PDFNAME + ".pdf";
        templateName = templateName + ".ftl";
        htmHandler(templatePath, templateName, localHtmlUrl, paramMap);// 生成html合同
        pdfHandler(localHtmlUrl, localPdfUrl);// 根据html合同生成pdf合同
        deleteFile(localHtmlUrl);// 删除html格式合同

        System.out.println("PDF生成成功");
    }

    /**
     * 生成HTML格式合同
     * @param templatePath
     * @param templateName
     * @param htmUrl
     * @param paramMap
     * @throws Exception
     */
    private static void htmHandler(String templatePath, String templateName,
                                   String htmUrl, Map<String, Object> paramMap) throws Exception {
        Configuration cfg = new Configuration();
        cfg.setDefaultEncoding("UTF-8");
        cfg.setDirectoryForTemplateLoading(new File(templatePath));
        Template template = cfg.getTemplate(templateName);
        File outHtmFile = new File(htmUrl);
        Writer out = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(outHtmFile),"UTF-8"));
        template.process(paramMap, out);

        out.close();
    }

    /**
     * 生成PDF格式合同
     * @param htmUrl
     * @param pdfUrl
     * @throws Exception
     * @throws IOException
     */
    private static void pdfHandler(String htmUrl, String pdfUrl)
            throws Exception, IOException {
        File htmFile = new File(htmUrl);
        File pdfFile = new File(pdfUrl);

        String url = htmFile.toURI().toURL().toString();

        OutputStream os = new FileOutputStream(pdfFile);

        ITextRenderer renderer = new ITextRenderer();
        //renderer.getSharedContext().setBaseURL("file:/"+"E:/IdeaProjects/demo/src/main/resources/image/");

        renderer.setDocument(url);

        ITextFontResolver fontResolver = renderer
                .getFontResolver();

        try {
            fontResolver.addFont(System.getProperty("user.dir")+"\\ruoyi-admin\\src\\main\\resources\\zhengshu\\font\\simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (Exception e) {
            e.printStackTrace();
        }

        renderer.layout();
        try {
            renderer.createPDF(os);
        } catch (Exception e) {
            e.printStackTrace();
        }
        os.close();
    }

    /**
     * 删除HTML文件
     * @param fileUrl
     */
    private static void deleteFile(String fileUrl) {
        File file = new File(fileUrl);
        file.delete();
    }



    private static boolean createDirectory(String folder) {
        File dir = new File(folder);
        if (dir.exists()) {
            return true;
        } else {
            return dir.mkdirs();
        }
    }

}
